﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace PrototypeZGame
{
    public class Field : Actor
    {
        
        public bool mouseOver;
        public List<Actor> onField;
        public List<Item> onFieldItems;
        public List<InventoryItem> onFieldInventoryItems;
        public List<Zombie> onFieldZombies;
        public List<Human> onFieldHumans;
        public List<Food> onFieldFood;
        public List<Weapon> onFieldWeapon;
        

        public void Clear()
        {
            onField.Clear();
            onFieldItems.Clear();
            onFieldInventoryItems.Clear();
            onFieldZombies.Clear();
            onFieldHumans.Clear();
            onFieldFood.Clear();
            onFieldWeapon.Clear();
        }

        public override Result blocking
        {
            get
            {
                if(_blocking == Result.BlockingField) return _blocking;

                foreach (Actor a in onField)
                {
                    if (a.blocking != Result.NoBlock)
                    {
                        return a.blocking;
                    }
                }

                return Result.NoBlock;
            }
            set
            {
            }
        }

        public override int moveCost
        {
            get
            {
                if (_blocking == Result.BlockingField)
                {
                    return int.MaxValue;
                }
                else
                {
                    int s = 1;
                    foreach (Actor a in onField)
                    {
                        s+=a.moveCost;
                    }
                    return s;
                }
            }

        }

        public Field(int X, int Y, World world)
            : base(X, Y, world)      
        {            
            mouseOver = false;
            tileset = world.tileset;
            onField = new List<Actor>();
            onFieldItems = new List<Item>();
            onFieldInventoryItems = new List<InventoryItem>();
            onFieldZombies = new List<Zombie>();
            onFieldHumans = new List<Human>();
            onFieldFood = new List<Food>();
            onFieldWeapon = new List<Weapon>();
            name = "Field(" + X + "," + Y + ")";
        }


        public void setFieldTypeFromColor(Color color){
            if (color == world.codeToColor[1])
            {
                tileType = TileType.Wall;
                _blocking = Result.BlockingField;
            }
            else if (color == world.codeToColor[2])
            {
                tileType = TileType.Grass;

            }
            else if (color == world.codeToColor[3])
            {
                tileType = TileType.Floor;

            }
            else if (color == world.codeToColor[4])
            {
                tileType = TileType.Street;

            }
            else if (color == world.codeToColor[5])
            {
                tileType = TileType.Grass;

                putOn(new Tree(position.x, position.y, world));
            }
            else if (color == world.codeToColor[6])
            {
                tileType = TileType.Floor;

                putOn(new Door(position.x, position.y, world));
            }
            else if (color == world.codeToColor[7])
            {
                tileType = TileType.Floor;

                
                putOn(getRandomShopItem());
            }

            else
            {
                tileType = TileType.None;

            }


        }


        private Actor getRandomShopItem()
        {
            int r = world.rand.Next(2);
            if (r == 0)
            {
                return new Food(position.x, position.y, world);
            }
            if (r == 1)
            {
                return new Weapon(position.x, position.y, world);
            }
            else
            {
                return new Food(position.x, position.y, world) ;
            }

        }

        public override void Draw()
        {
            base.Draw();

            foreach (Actor a in onField)
            {
                a.Draw();
            }


            if (mouseOver)
            {
                Rectangle mouseOverRectangle = new Rectangle(((int)TileType.OnMouseOver % 16) * fieldResolution, fieldResolution * ((int)TileType.OnMouseOver / 16), fieldResolution, fieldResolution);
                world.spriteBatch.Draw(world.tileset, destinationRectangle, mouseOverRectangle, Color.White);
            }
            
            world.fieldsDrawn++;
            
        }


        public new void move(int x, int y)
        {
        }

        public bool putOn(Actor actor)
        {
            onField.Add(actor);

            Item item = actor as Item;
            if (item != null)
            {
                onFieldItems.Add(item);

                InventoryItem iItem = item as InventoryItem;
                if (iItem != null)
                {
                    onFieldInventoryItems.Add(iItem);

                    Food food = iItem as Food;
                    if (food != null)
                    {
                        onFieldFood.Add(food);
                        return true;
                    }

                    Weapon weapon = iItem as Weapon;
                    if (weapon != null)
                    {
                        onFieldWeapon.Add(weapon);
                        return true;
                    }
                }
                return true;
            }

            Human human = actor as Human;
            if (human != null)
            {
                onFieldHumans.Add(human);
                return true;
            }


            Zombie zombie = actor as Zombie;
            if (zombie != null)
            {
                onFieldZombies.Add(zombie);
                return true;
            }

            return true;
        }

        public bool takeFrom(Actor actor)
        {
            onField.Remove(actor);

            Item item = actor as Item;
            if (item != null)
            {
                onFieldItems.Remove(item);

                InventoryItem iItem = item as InventoryItem;
                if (iItem != null)
                {
                    onFieldInventoryItems.Remove(iItem);
                    
                    Food food = iItem as Food;
                    if (food != null)
                    {
                        onFieldFood.Remove(food);
                        return true;
                    }

                    Weapon weapon = iItem as Weapon;
                    if (weapon != null)
                    {
                        onFieldWeapon.Remove(weapon);
                        return true;
                    }
                }
                return true;
            }

            Human human = actor as Human;
            if (human != null)
            {
                onFieldHumans.Remove(human);
                return true;
            }


            Zombie zombie = actor as Zombie;
            if (zombie != null)
            {
                onFieldZombies.Remove(zombie);
                return true;
            }

            
            return true;
        }

        public string getFieldInfoString()
        {
            string field = "", units = "", items = "", inventoryItems = "";
            field += this.position + "\n";

            foreach (Actor a in onField)
            {
                Unit unit = a as Unit;
                if (unit != null)
                {
                    units += unit.getInfoString() + "\n";
                }

                Item item = a as Item;
                if (item != null)
                {
                    items += item.name + "\n";
                }
            }

            return field + units + items;
        }



    }
}
